<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
   
</head>
<body>
   <input type="text" name="" id="inp">
</body>
<script>
  function debounce(fn) {
    let timeout = null; // 创建一个标记用来存放定时器的返回值
    return function () {
      clearTimeout(timeout); // 每当用户输入的时候把前一个 setTimeout clear 掉
      timeout = setTimeout(() => { // 然后又创建一个新的 setTimeout, 这样就能保证输入字符后的 interval 间隔内如果还有字符输入的话，就不会执行 fn 函数
        // fn()   这样的话fn()是window调用的（setTimeout的中this指向window，而不是inp）
        fn.apply(this, arguments);   
      }, 500);
    };
  }
  function sayHi() {
    console.log('this:', this);
    
    this.style.color = 'red' //inp添加监听事件的回调，调用了sayHi，谁调用this指向谁，所以上面fn.apply(this, arguments) 中的this指向input,  fn.appply(this)相当于this.fn(),也就是input里面执行了fn也就是（sayHi），就可以获取并改变颜色
    console.log('防抖成功');
  }

  var inp = document.getElementById('inp');
  inp.addEventListener('input', debounce(sayHi)); // 防抖
  </script>
</html>